<template>
  <div>
    <el-card class="box-card" shadow="hover">
      <!-- 卡片顶部的添加品牌按钮 -->
      <el-button
        type="primary"
        size="default"
        icon="Plus"
        @click="addTrademark"
        v-has="`btn.Trademark.add`"
      >
        添加品牌
      </el-button>
      <!-- 表格组件:用于展示已有的数据 -->
      <!--  table
                border:设置边框
              table-colum
                label:表头名称
                width:列宽度
                align:单元格对齐方式
        -->
      <el-table
        :data="trademarkArr"
        stripe
        height="62.3vh"
        style="width: 100%; margin: 20px 0"
      >
        <!-- 序号列 -->
        <el-table-column type="index" label="序号" width="80" align="center" />
        <!-- table-column:默认展示数据用div-->
        <el-table-column prop="tmName" label="品牌名称" align="center">
          <!-- 使用插槽代替 prop -->
          <!-- <template #default="{ row }">
              <h1 style="color:blueviolet;">{{ row.tmName }}</h1>
            </template> -->
        </el-table-column>
        <el-table-column label="品牌LOGO" align="center">
          <!-- 使用el-table-column提供的作用域插槽获取到图片的地址 -->
          <template #default="{ row }">
            <img
              :src="row.logoUrl"
              style="width: 65px; height: 65px"
              alt="logo"
            />
          </template>
        </el-table-column>
        <el-table-column label="品牌操作" align="center">
          <!-- 使用插槽获取当前操作的品牌对象 -->
          <template #default="{ row }">
            <!-- 修改品牌按钮 -->
            <el-button
              type="warning"
              size="small"
              @click="updateTrademark(row)"
              icon="Edit"
              v-has="`btn.Trademark.update`"
            ></el-button>
            <!-- 删除品牌按钮 -->
            <el-popconfirm
              :title="`确认要删除${row.tmName}吗?`"
              width="250"
              @confirm="deleteTrademark(row.id)"
            >
              <template #reference>
                <el-button
                  type="danger"
                  size="small"
                  icon="Delete"
                  v-has="`btn.Trademark.remove`"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页组件 -->
      <!-- pagination
                v-model:current-page:当前页
                v-model:page-size:每页显示的记录数
                :page-sizes:选择每页显示的记录数
                :small="false"：是否使用小型分页样式
                :background="true"：是否为分页按钮添加背景色
                layout：控制显示哪些内容
                :total="400"：总记录数
                @size-change="handleSizeChange"：当每页显示的条数改变时触发
                @current-change="handleCurrentChange"：当页码改变时
         -->
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="limit"
        :page-sizes="[5, 10, 20]"
        :small="true"
        background
        layout="prev, pager, next,jumper,->,sizes,total"
        :total="total"
        @change="getHasTrademark"
      />
    </el-card>
    <!-- 对话框组件:再添加品牌和修改已有品牌的业务时使用 -->
    <!--属性：v-model:控制对话框的显示与隐藏
      title:对话框的标题-->
    <el-dialog v-model="dialogFormVisible" draggable width="43%">
      <template #header>
        <h1 style="font-size: large; font-weight: bold">
          {{ trademarkParams.id ? '修改品牌' : '添加品牌' }}
        </h1>
      </template>
      <el-form
        label-position="left"
        label-width="110px"
        :model="trademarkParams"
        :rules="rules"
        ref="formRef"
      >
        <el-form-item label="品牌名称：" prop="tmName">
          <el-input
            v-model="trademarkParams.tmName"
            style="width: 90%"
            placeholder="请输入品牌名称"
          />
        </el-form-item>
        <el-form-item label="品牌LOGO：" prop="logoUrl">
          <!-- upload 组件属性
              action:上传图片的地址要加前缀/api,代理服务不发送本次请求
              multiple:是否支持多文件上传
              show-file-list:是否显示已上传文件列表
              :before-upload:这个钩子在图片上传前触发的钩子,参数为上传的文件
              :on-success:文件上传成功后触发的钩子
             -->
          <el-upload
            action="/api/admin/product/fileUpload"
            :before-upload="beforeAvatarUpload"
            :on-success="handleAvatarSuccess"
            style="width: 70%"
            ref="upload"
            drag
            class="upload-demo"
          >
            <!-- 上传图标和图片轮流展示 -->
            <img
              v-if="trademarkParams.logoUrl"
              :src="trademarkParams.logoUrl"
              style="width: 100%"
            />
            <template v-if="!trademarkParams.logoUrl">
              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
              <div class="el-upload__text">
                将文件拖到此处，或
                <em>点击上传</em>
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <div style="margin-top: -10px">
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="confirm">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="TradeMark">
import { ElMessage, type UploadProps } from 'element-plus'
import {
  reqAddOrUpdateTrademark,
  reqDeleteTradeMark,
  reqHasTrademark,
} from '@/api/product/trademark'
import { nextTick, onMounted, reactive, ref } from 'vue'
import type { Records, TradeMark } from '../../../api/product/trademark/type'

// 当前页码
let pageNo = ref(1)
// 定义每一页展示多少条数据
let limit = ref(5)
// 存储获取到的品牌的总数
let total = ref<number>(0)
// 存储已有品牌的数据
let trademarkArr = ref<Records>([]) // 此处注意要用ref定义不能使用reactive,后面要对整个trademarkArr进行替换
// 控制对话框的显示与隐藏
let dialogFormVisible = ref(false)
// 定义收集新增品牌数据
const trademarkParams = reactive<TradeMark>({
  tmName: '',
  logoUrl: '',
})
// 接收el-upload组件的实例对象获取clearFiles方法
let upload = ref()
// 接收el-form组件实例对象获取validate方法
let formRef = ref()

// 将获取已有品牌的接口封装为一个函数，在任何情况下获取数据调用函数即可
const getHasTrademark = async () => {
  let result = await reqHasTrademark(pageNo.value, limit.value)
  if (result.code === 200) {
    // 存储品牌的总个数
    total.value = result.data.total
    trademarkArr.value = result.data.records
  }
}
// 组件挂载完毕时发送请求获取第一页品牌数据
onMounted(() => {
  getHasTrademark()
})
// 当分页器页码发生变化时触发
// 对于当前页码发生变化的自定义实际,组件el-pagination给父组件回传了数据
/* const changePageNo = (currentPage: number, pageSize: number) => {
  console.log(currentPage, pageSize) // 自定义事件传递了当前页码和每页展示多少条数据
  // 当前页码发生变化时，再次发请求获取对应页码的数据并展示
  getHasTrademark()
} */

// 添加品牌的回调
const addTrademark = () => {
  // 清除表单中的数据
  trademarkParams.tmName = ''
  trademarkParams.logoUrl = ''
  trademarkParams.id = undefined
  // 显示对话框
  dialogFormVisible.value = true
  // 清除上一次表单校验的错误信息
  // console.log(formRef.value) undefined // 第一次点击时el-form组件还未渲染 formRef.value为undefined
  // formRef.value ? formRef.value.clearValidate(['tmName', 'logoUrl']) : ''// if写法
  // formRef.value?.clearValidate(['tmName', 'logoUrl']) // 使用TS类型进行处理
  nextTick(() => {
    // 使用nextTick处理
    // 等组件渲染完毕后在执行
    formRef.value.clearValidate(['tmName', 'logoUrl'])
  })
}
// 修改已有品牌的回调
const updateTrademark = (row: TradeMark) => {
  // console.log(raw) // 存储的是当前修改商品的全部信息
  // 将当前修改商品的全部信息赋值给trademarkParams
  Object.assign(trademarkParams, row)
  /* trademarkParams.tmName = raw.tmName
  trademarkParams.logoUrl = raw.logoUrl
  // 添加品牌数据无需设置id，修改品牌数据需要设置id
  trademarkParams.id = raw.id */
  // 显示对话框
  dialogFormVisible.value = true
  // 清除上一次表单校验的错误信息
  formRef.value?.clearValidate(['tmName', 'logoUrl'])
}
// 气泡确认框按钮删除已有品牌的回调
const deleteTrademark = async (id: number) => {
  // 向服务器发送请求
  let result = await reqDeleteTradeMark(id)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    // 删除成功重新获取数据
    getHasTrademark()
  } else {
    ElMessage({
      type: 'error',
      message: result.data,
    })
  }
}
// 对话框底部取消按钮
const cancel = () => {
  // 隐藏对话框
  dialogFormVisible.value = false
  // 清空已上传的文件列表
  upload.value.clearFiles()
}
// 对话框底部确定按钮
const confirm = async () => {
  // 1.对整个表单进行校验
  await formRef.value.validate() // 表单验证成功后才会继续执行
  // 2.向服务器发送增加/修改请求(有id为修改，无id为增加)
  const result = await reqAddOrUpdateTrademark(trademarkParams)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: trademarkParams.id ? '修改成功' : '添加成功',
    })
    // 3.添加/修改成功隐藏对话框
    dialogFormVisible.value = false
    // 清空已上传的文件列表
    upload.value.clearFiles()
    // 4.重新获取全部的数据
    getHasTrademark()
    if (!trademarkParams.id) pageNo.value = 1
  } else {
    ElMessage({
      type: 'error',
      message: trademarkParams.id ? '修改失败' : '添加失败',
    })
  }
}
//上传图片组件->上传图片之前触发的钩子函数，在上传文件前，约束图片的类型和大小
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  // console.log(rawFile) //{name: "1.jpg", size: 1024, type: "image/jpeg"}
  // 要求上传的图片的格式必须为 jpg/png/gif <4M
  if (
    rawFile.type === 'image/jpeg' ||
    rawFile.type === 'image/png' ||
    rawFile.type === 'image/gif'
  ) {
    if (rawFile.size <= 4 * 1024 * 1024) {
      return true // 上传
    } else {
      ElMessage({
        type: 'error',
        message: '上传的图片大小必须小于4M',
      })
      return false // 终止上传
    }
  } else {
    ElMessage({
      type: 'error',
      message: '上传的图片格式必须为jpg/png/gif',
    })
    return false // 终止上传
  }
}
// 上传图片组件->上传成功后触发的钩子函数，收集上传成功后服务器返回的图片地址
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response, // 上传成功后服务器返回的数据
) => {
  // 收集上传成功后服务器返回的图片地址，在添加品牌时使用
  trademarkParams.logoUrl = response.data
  // 图片上传成功,清除掉对应图片校验结果
  formRef.value.clearValidate('logoUrl')
}
// 定义表单校验规则
const rules = {
  tmName: [
    // required校验规则会让属性名前出现*，表示必填
    { required: true, message: '请输入品牌名称', trigger: 'blur' },
    { min: 2, message: '请最少输入两个字符', trigger: 'blur' },
  ],
  logoUrl: [
    {
      required: true,
      message: '请选择要上传的LOGO图片',
    },
  ],
}
</script>

<style scoped></style>
